package com.fin.zw.intelligentbot.service;

import com.fin.zw.intelligentbot.entity.*;
import com.fin.zw.intelligentbot.enums.RobotStatus;
import com.fin.zw.intelligentbot.model.request.RobotInfoRequest;
import com.fin.zw.intelligentbot.model.response.RobotInfoResponse;
import com.fin.zw.intelligentbot.model.session.SessionModel;
import com.fin.zw.intelligentbot.repository.*;
import com.querydsl.core.BooleanBuilder;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service("robotInfoService")
public class RobotInfoService {
    private static final Logger log = LoggerFactory.getLogger(RobotInfoService.class);

    @Autowired
    private RobotInfoRepository robotInfoRepository;

    @Autowired
    private SceneInfoRepository sceneInfoRepository;

    @Autowired
    private LineInfoRepository lineInfoRepository;

    @Autowired
    private CompanyRepository companyRepository;

    @Autowired
    private AiConfigurationRepository aiConfigurationRepository;

    /**
     * 分页查询机器人信息
     * @param pageable
     * @param request
     * @param sessionModel
     * @return
     */
    public Page<RobotInfoResponse> queryRobotInfoAll(Pageable pageable,
                                                     RobotInfoRequest request,
                                                     SessionModel sessionModel){
        BooleanBuilder builder = new BooleanBuilder();
        QRobotInfo qRobotInfo = QRobotInfo.robotInfo;
        if(sessionModel.getCompanyId() != null){
            builder.and(qRobotInfo.company.id.eq(sessionModel.getCompanyId()));
        }
        if(request.getName() != null){
            builder.and(qRobotInfo.name.eq(request.getName()));
        }
        if(request.getCode() != null){
            builder.and(qRobotInfo.code.eq(request.getCode()));
        }
        Page<RobotInfo> infoPage = robotInfoRepository.findAll(builder,pageable);
        Page<RobotInfoResponse> page = infoPage.map(robotInfo -> {
            return robot2ResposeRobot(robotInfo);
        });
        return page;
    }

    /**
     * 将实体类型集合转换成相应类型集合
     * @param robotInfo
     * @return
     */
    private RobotInfoResponse robot2ResposeRobot(RobotInfo robotInfo) {
        RobotInfoResponse response = new RobotInfoResponse();
        BeanUtils.copyProperties(robotInfo,response);
        if(Objects.nonNull(robotInfo.getGateway())){
            response.setLineId(robotInfo.getGateway().getId());
            response.setLineName(robotInfo.getGateway().getName());
            response.setLinePrefix(robotInfo.getGateway().getPrefix());
        }
        if(Objects.nonNull(robotInfo.getSceneInfo())){
            response.setSceId(robotInfo.getSceneInfo().getId());
            response.setSceName(robotInfo.getSceneInfo().getName());
        }
        if(Objects.nonNull(robotInfo.getCompany())){
            response.setCompanyId(robotInfo.getCompany().getId());
            response.setCompanyName(robotInfo.getCompany().getName());
        }
        return response;
    }

    public List<RobotInfoResponse> fetch(RobotInfoRequest request, SessionModel sessionModel)
    {
        BooleanBuilder builder = new BooleanBuilder();
        QRobotInfo qRobotInfo = QRobotInfo.robotInfo;
        if(sessionModel.getCompanyId() != null){
            builder.and(qRobotInfo.company.id.eq(sessionModel.getCompanyId()));
        }
        List<RobotInfo> robots = IterableUtils.toList(robotInfoRepository.findAll(builder));

        return robots.stream().map(robot->this.robot2ResposeRobot(robot)).collect(Collectors.toList());
    }


    /**
     * 机器人创建
     * @param request
     */
    public void createRobotInfo(RobotInfoRequest request,
                                SessionModel sessionModel){
        RobotInfo robotInfo = new RobotInfo();
        BeanUtils.copyProperties(request,robotInfo);
        robotInfo.setStatus(RobotStatus.IDLE);
        setRobotInfo(robotInfo, request, sessionModel);
        robotInfoRepository.save(robotInfo);
    }

    /**
     * 机器人信息更新
     * @param request
     */
    public void updateRobotInfo(RobotInfoRequest request, SessionModel sessionModel) {
        Optional<RobotInfo> optional = robotInfoRepository.findById(request.getId());
        if(!optional.isPresent()){
            log.info("机器人信息不存在");
            throw new RuntimeException("机器人信息不存在");
        }
        RobotInfo robotInfo = optional.get();
        if(request.getName()!=null&&!"".equals(request.getName()))
            robotInfo.setName(request.getName());
        if(request.getName()!=null&&!"".equals(request.getName()))
            robotInfo.setCode(request.getCode());
        if(StringUtils.isNotEmpty(request.getStatus()))
            robotInfo.setStatus(RobotStatus.valueOf(request.getStatus()));
        robotInfo.setDisplayName(request.getDisplayName());
        setRobotInfo(robotInfo, request, sessionModel);
        robotInfoRepository.save(robotInfo);
    }


    /**
     * 机器人删除功能
     * @param id
     * @param sessionModel
     */
    public void deleteRobotInfoById(String id,SessionModel sessionModel){
        Optional<RobotInfo> optional = robotInfoRepository.findById(id);
        if(!optional.isPresent()){
            log.info("机器人信息不存在");
            throw new RuntimeException("机器人信息不存在");
        }
        RobotInfo robotInfo = optional.get();
        if(sessionModel.getCompanyId() != null){
            log.info("没有删除权限，请找管理人员");
            throw new RuntimeException("没有删除权限，请找管理人员");
        }
        if(Objects.nonNull(robotInfo.getCompany())){
            log.info("该机器人已经分配，不允许删除");
            throw new RuntimeException("该机器人已经分配，不允许删除");
        }
        robotInfoRepository.delete(robotInfo);
    }

    /**
     * 机器人回收
     * @param ids
     */
    public void recoveryRobot(List<String> ids){
        Iterator<RobotInfo> iterator = robotInfoRepository.findAll(QRobotInfo.robotInfo.id.in(ids)).iterator();
        List<RobotInfo> list = new ArrayList<>();
        while (iterator.hasNext()){
            RobotInfo robotInfo = iterator.next();
            robotInfo.setCompany(null);
            list.add(robotInfo);
        }
        robotInfoRepository.saveAll(list);
    }

    /**
     * 设置机器人属性值
     * @param robotInfo
     * @param request
     */
    public void setRobotInfo(RobotInfo robotInfo, RobotInfoRequest request, SessionModel sessionModel) {
        String sceId = request.getSceId();
        String lineId = request.getLineId();
        String nlpId = request.getNlpId();//智能语音id
        String asrId = request.getAsrId();//语音识别id
        String ttsId = request.getTtsId();//语音合成id
        if (StringUtils.isNotEmpty(sessionModel.getCompanyId())) {
            Optional<Company> optional = companyRepository.findById(sessionModel.getCompanyId());
            if (optional.isPresent()) {
                robotInfo.setCompany(optional.get());
            }
        } else {
            String companyId = request.getCompanyId();
            if (StringUtils.isNoneBlank(companyId)) {
                companyRepository.findById(companyId).ifPresent(company -> {
                    robotInfo.setCompany(company);
                    return;
                });
            }
        }

        if(lineId != null && !lineId.trim().equals("")){
            Optional<LineInfo> circuitOptional = lineInfoRepository.findById(lineId);
            if(!circuitOptional.isPresent()){
                log.info("选择的线路信息不存在");
                throw new RuntimeException("选择的线路信息不存在");
            }
            LineInfo circuit = circuitOptional.get();
            robotInfo.setGateway(circuit);
        }
        if(sceId != null && !sceId.trim().equals("")){
            Optional<SceneInfo> sceneInfoOptional = sceneInfoRepository.findById(sceId);
            if(!sceneInfoOptional.isPresent()){
                log.info("选择的场景信息不存在");
                throw new RuntimeException("选择的场景信息不存在");
            }
            SceneInfo sceneInfo = sceneInfoOptional.get();
            robotInfo.setSceneInfo(sceneInfo);
        }
        if(nlpId != null && !nlpId.trim().equals("")){
            Optional<AiConfiguration> aiConfigurationOptional = aiConfigurationRepository.findById(nlpId);
            if(!aiConfigurationOptional.isPresent()){
                log.error("选择的智能语音信息不存在");
                throw new RuntimeException("选择的智能语音信息不存在");
            }
            AiConfiguration aiConfig = aiConfigurationOptional.get();
            robotInfo.setNlp(aiConfig);
        }
        if(asrId != null && !asrId.trim().equals("")){
            Optional<AiConfiguration> aiConfigurationOptional = aiConfigurationRepository.findById(asrId);
            if(!aiConfigurationOptional.isPresent()){
                log.error("选择的语音识别信息不存在");
                throw new RuntimeException("选择的语音识别信息不存在");
            }
            AiConfiguration aiConfig = aiConfigurationOptional.get();
            robotInfo.setAsr(aiConfig);
        }
        if(ttsId != null && !ttsId.trim().equals("")){
            Optional<AiConfiguration> aiConfigurationOptional = aiConfigurationRepository.findById(ttsId);
            if(!aiConfigurationOptional.isPresent()){
                log.error("选择的语音合成信息不存在");
                throw new RuntimeException("选择的语音合成信息不存在");
            }
            AiConfiguration aiConfig = aiConfigurationOptional.get();
            robotInfo.setTts(aiConfig);
        }
    }
}
